package uk.ac.lkl.lpp.ui;



import java.util.ArrayList;

import java.awt.BorderLayout;
import java.awt.Point;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import javax.swing.JDialog;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;

import uk.ac.lkl.common.util.ds.AbstractNotifyingList;
import uk.ac.lkl.common.util.ds.NotifyingList;
import uk.ac.lkl.common.util.ds.NotifyingMap;
import uk.ac.lkl.lpp.model.PedagogyPlanModel;
import uk.ac.lkl.lpp.model.ldo.TeachingMethod;


/**
 * Dialog for selecting TMs from the available list. TMs are displayed with a
 * checkbox that displays and controls their "selected" attribute. Selected TMs
 * will appear in the TMs, linking and Allocate panels. Unselected ones will
 * not.
 * 
 * The dialog is constructed as a singleton, hence the private constructor. To
 * use it, call {@showDialog}.
 * 
 * @author yish
 * 
 */
public class TeachingMethodsSelectDialog extends JDialog {

    private static final long serialVersionUID = 1L;


    private static final String MESSAGES_KEY = "TeachingMethodsSelectDialog";

    private static NotifyingMap<TeachingMethod, Float> hoursMap;

    /**
     * this is where the TMs live
     */
    private Box tmsBox = new Box(BoxLayout.Y_AXIS);


    /**
     * the single instance of this class.
     */
    private static final TeachingMethodsSelectDialog theDialog = new TeachingMethodsSelectDialog();


    /**
     * the model from which we retrieve the list of TMs.
     */
    private PedagogyPlanModel plan;


    private AbstractNotifyingList<TeachingMethod> allTeachingMethods;


    private AbstractNotifyingList<TeachingMethod> selectedTeachingMethods;


    public static void showDialog(PedagogyPlanModel plan, Point location) {
        hoursMap = plan.getMap(
                "TeachingMethodHoursAllocation",
                TeachingMethod.class,
                Float.class);

        theDialog.setLocation(location);
        showDialog(plan);
    }


    public static void showDialog(PedagogyPlanModel plan) {
        theDialog.setPlan(plan);
        theDialog.pack();
        theDialog.setVisible(true);
    }


    private void setPlan(PedagogyPlanModel plan) {
        // always refresh list so get split between selected and unselected
        //if (plan == this.plan)
        //    return;
        this.plan = plan;
        refreshList();
    }


    private TeachingMethodsSelectDialog() {
        setLayout(new BorderLayout());
        setAlwaysOnTop(true);
        add(Messages.getJLabel(MESSAGES_KEY), BorderLayout.NORTH);
        add(tmsBox, BorderLayout.CENTER);
    }


    private void refreshList() {
        allTeachingMethods = plan.getList("main", TeachingMethod.class);
        selectedTeachingMethods = plan
                .getList("selected", TeachingMethod.class);
        tmsBox.removeAll();

        for (TeachingMethod teachingMethod : selectedTeachingMethods)
            tmsBox.add(new TMSelector(teachingMethod));

        // hack to divide into those selected and those unselected.
        ArrayList<TeachingMethod> unselectedTeachingMethods = new ArrayList<TeachingMethod>(
                allTeachingMethods);

        unselectedTeachingMethods.removeAll(selectedTeachingMethods);

        for (TeachingMethod teachingMethod : unselectedTeachingMethods)
            tmsBox.add(new TMSelector(teachingMethod));
    }

    private final class TMSelector extends Box implements ActionListener {

        private static final long serialVersionUID = 1L;


        TeachingMethod teachingMethod;


        JCheckBox checkBox = new JCheckBox();


        public TMSelector(TeachingMethod teachingMethod) {
            super(BoxLayout.X_AXIS);
            this.teachingMethod = teachingMethod;

            add(checkBox);
            checkBox.addActionListener(this);
            checkBox.setSelected(selectedTeachingMethods
                    .contains(teachingMethod));

            add(Messages.makeJButton(
                                     teachingMethod.getTitle(),
                                     null,
                                     teachingMethod.getDescription(),
                                     teachingMethod.getLink()));
            add(Box.createGlue());
        }


        public void actionPerformed(ActionEvent e) {
            boolean selected = checkBox.isSelected();
            if (selected){
                selectedTeachingMethods.add(teachingMethod);
            }else {
            	// semi-hack to make the total behave as expected.
            	// should really recode the TM class as having time properties. 
            	
            	hoursMap.put(teachingMethod,new Float(0));
                selectedTeachingMethods.remove(teachingMethod);
            }
        }
    }
}
